<template>
  <div class="captcha-box"
       :style="{'background-image': 'url(' + baseStyle.bgImage + ')', 'width': (baseStyle.width + baseStyle.margin) + 'px',
       'height': (baseStyle.height + baseStyle.margin) + 'px', 'border-radius': baseStyle.borderRadius + 'px'}">
    <div class="captcha-container" :style="{'width': baseStyle.width + 'px', 'height': baseStyle.height + 'px'}">

      <div class="captcha-title" :style="{'justify-content': baseStyle.titleAlign}">
        <span :style="{'color': baseStyle.titleColor, 'font-size': baseStyle.titleFontSize + 'px',
        'font-weight': baseStyle.titleWeight}">{{ baseStyle.title }}</span>
      </div>

      <div class="captcha-content">
        <img class="captcha-content-bg" :src="captchaData.captchaBackgroundImage" ref="captcha_bg_img"/>
        <img class="captcha-content-move" :src="captchaData.captchaTemplateImage" ref="captcha_move_img"/>
      </div>

      <div class="captcha-track">
        <div class="captcha-track-bar">
          <div class="captcha-track-bar-mask" ref="captcha_slider_move_track"
               :style="{borderColor: baseStyle.trackerColor, backgroundColor: baseStyle.trackerBgColor}"></div>
          <div class="captcha-track-bar-line"></div>
        </div>
        <div class="captcha-track-slider"
             @mousedown.prevent="sliderDown"
             ref="slider_move_btn"></div>
      </div>

      <div class="captcha-footer">
        <!-- 占位 -->
        <div style="width: 80%;"></div>
        <div class="captcha-foot-content">
          <div class="captcha-foot-content-refresh" @click="refreshCaptcha">
          </div>
          <div class="captcha-foot-content-close" @click="closeCaptcha">
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {computed, ref} from 'vue'

const props = defineProps({
  /** 基础样式 */
  baseStyle: {
    type: Object,
    default: function () {
      return {}
    }
  },
  /** 验证码数据 */
  captchaData: {
    type: Object,
    default: function () {
      return {}
    }
  }
})

const trackList = ref([])
const startTime = ref(null)
const stopTime = ref(null)
const startX = ref(null)
const startY = ref(null)

const captcha_bg_img = ref()
const slider_move_btn = ref()
const captcha_move_img = ref()
const captcha_slider_move_track = ref()

const boxWidth = computed(()=> captcha_bg_img.value.width - slider_move_btn.value.offsetWidth)

// 鼠标按下事件
const sliderDown = (res) => {
  this.trackList = [];
  let startX = res.pageX;
  let startY = res.pageY;
  let startTime = new Date().getTime();
  this.startX = startX;
  this.startY = startY;
  this.startTime = startTime;
  this.trackList.push({
    x: res.pageX - startX,
    y: res.pageY - startY,
    type: 'down',
    t: new Date().getTime() - this.startTime
  });

  slider_move_btn.value.addEventListener("mousemove", sliderMove);
  slider_move_btn.value.addEventListener("mouseup", sliderUp);
}
// 鼠标移动事件
const sliderMove = (res) => {
  let moveX = res.pageX - this.startX;
  this.trackList.push({
    x: moveX,
    y: res.pageY - this.startY,
    type: 'move',
    t: new Date().getTime() - this.startTime
  });

  if (moveX < 0) {
    moveX = 0;
  } else if (moveX > this.boxWidth) {
    moveX = this.boxWidth;
  }
  slider_move_btn.value.style.transform = "translate(" + moveX + "px, 0px)";
  captcha_move_img.value.style.transform = "translate(" + moveX + "px, 0px)";
  captcha_slider_move_track.value.style.width = moveX + "px";
}
// 鼠标抬起事件
const sliderUp = (res) => {
  slider_move_btn.value.removeEventListener("mousemove", sliderMove);
  slider_move_btn.value.removeEventListener("mouseup", sliderUp);
  let moveX = res.pageX - this.startX;
  this.stopTime = new Date().getTime();
  this.trackList.push({
    x: moveX,
    y: res.pageY - this.startY,
    type: 'up',
    t: new Date().getTime() - this.startTime
  });
  slider_move_btn.value.style.transform = "translate(" + moveX + "px, 0px)";
  captcha_move_img.value.style.transform = "translate(" + moveX + "px, 0px)";
  captcha_slider_move_track.value.style.width = moveX + "px";

  // 收集轨迹记录 并传入后台验证
  let captchaValidate = {
    bgImageWidth: this.$refs['captcha_bg_img'].width,
    bgImageHeight: this.$refs['captcha_bg_img'].height,
    sliderImageWidth: captcha_move_img.value.width,
    sliderImageHeight: captcha_move_img.value.height,
    startSlidingTime: this.startTime,
    endSlidingTime: this.stopTime,
    trackList: this.trackList,
    data: null
  }
  this.$emit("validateCaptcha", captchaValidate);
}

// 还原滑块
const reset = () => {
  slider_move_btn.value.style.transform = "translate(0px, 0px)";
  captcha_move_img.value.style.transform = "translate(0px, 0px)";
  captcha_slider_move_track.value.style.width = "0px";
}

// 关闭验证码事件
const closeCaptcha = () => {
  this.$emit("closeCaptcha");
}
// 刷新验证码事件
const refreshCaptcha = () => {
  this.$emit("refreshCaptcha");
}
</script>

<style scoped>
.captcha-box {
  display: flex;
  justify-content: center;
  align-items: center;
}

.captcha-container {
  display: flex;
  flex-direction: column;
}

.captcha-title {
  width: 100%;
  height: 10%;
  display: flex;
  align-items: center;
}

.captcha-content {
  width: 100%;
  height: 65%;
  position: relative;
}

.captcha-content-bg {
  width: 100%;
  height: 100%;
  border-radius: 5px;
}

.captcha-content-move {
  left: 0;
  position: absolute;
  transform: translate(0px, 0px);
  height: 100%;
}

.captcha-footer {
  width: 100%;
  height: 10%;
  display: flex;
  align-items: center;
}

.captcha-foot-content {
  width: 20%;
  display: flex;
  justify-content: space-around;
}

.captcha-foot-content-refresh {
  width: 20px;
  height: 20px;
  background: url(~@/assets/images/icon.png) no-repeat 0 -167px;
}

.captcha-foot-content-close {
  width: 20px;
  height: 20px;
  background: url(~@/assets/images/icon.png) no-repeat 0 -14px;
}

.captcha-track {
  width: 100%;
  height: 15%;
  position: relative;
  display: flex;
  align-items: center;
}

.captcha-track-bar {
  width: 100%;
  height: 65%;
  background-color: #f5f5f5;
  opacity: .8;
  border-radius: 4px;
}

.captcha-track-bar-mask {
  border-color: rgb(239, 156, 13);
  background-color: rgb(247, 182, 69);
  width: 0px;
}


@keyframes captchaTrackBarLine {
  from {
    left: 0;
  }

  to {
    left: 100%;
  }
}

.captcha-track-bar-line {
  animation: captchaTrackBarLine 2s infinite;
  height: 65%;
  width: 5px;
  background-color: #fff;
  position: absolute;
  filter: opacity(0.5);
  box-shadow: 1px 1px 1px #fff;
}

.captcha-track-slider {
  background-image: url(https://minio.tianai.cloud/public/captcha-btn/btn3.png);
  background-repeat: no-repeat;
  background-size: contain;
  transform: translate(0px, 0px);
  position: absolute;
  width: 53px;
  height: 85%;
  border-radius: 5px;
}
</style>
